/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package hibernatecontrolador;

import hibernatecontrolador.exceptions.IllegalOrphanException;
import hibernatecontrolador.exceptions.NonexistentEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import hibernatemodelo.Lugar;
import hibernatemodelo.Contacto;
import hibernatemodelo.Evento;
import hibernatemodelo.Invitar;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author Z510
 */
public class EventoJpaController implements Serializable {

    public EventoJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Evento evento) {
        if (evento.getInvitarCollection() == null) {
            evento.setInvitarCollection(new ArrayList<Invitar>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Lugar lugar = evento.getLugar();
            if (lugar != null) {
                lugar = em.getReference(lugar.getClass(), lugar.getId());
                evento.setLugar(lugar);
            }
            Contacto idcreador = evento.getIdcreador();
            if (idcreador != null) {
                idcreador = em.getReference(idcreador.getClass(), idcreador.getId());
                evento.setIdcreador(idcreador);
            }
            Collection<Invitar> attachedInvitarCollection = new ArrayList<Invitar>();
            for (Invitar invitarCollectionInvitarToAttach : evento.getInvitarCollection()) {
                invitarCollectionInvitarToAttach = em.getReference(invitarCollectionInvitarToAttach.getClass(), invitarCollectionInvitarToAttach.getId());
                attachedInvitarCollection.add(invitarCollectionInvitarToAttach);
            }
            evento.setInvitarCollection(attachedInvitarCollection);
            em.persist(evento);
            if (lugar != null) {
                Evento oldIdeventoOfLugar = lugar.getIdevento();
                if (oldIdeventoOfLugar != null) {
                    oldIdeventoOfLugar.setLugar(null);
                    oldIdeventoOfLugar = em.merge(oldIdeventoOfLugar);
                }
                lugar.setIdevento(evento);
                lugar = em.merge(lugar);
            }
            if (idcreador != null) {
                idcreador.getEventoCollection().add(evento);
                idcreador = em.merge(idcreador);
            }
            for (Invitar invitarCollectionInvitar : evento.getInvitarCollection()) {
                Evento oldIdeventoOfInvitarCollectionInvitar = invitarCollectionInvitar.getIdevento();
                invitarCollectionInvitar.setIdevento(evento);
                invitarCollectionInvitar = em.merge(invitarCollectionInvitar);
                if (oldIdeventoOfInvitarCollectionInvitar != null) {
                    oldIdeventoOfInvitarCollectionInvitar.getInvitarCollection().remove(invitarCollectionInvitar);
                    oldIdeventoOfInvitarCollectionInvitar = em.merge(oldIdeventoOfInvitarCollectionInvitar);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Evento evento) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Evento persistentEvento = em.find(Evento.class, evento.getId());
            Lugar lugarOld = persistentEvento.getLugar();
            Lugar lugarNew = evento.getLugar();
            Contacto idcreadorOld = persistentEvento.getIdcreador();
            Contacto idcreadorNew = evento.getIdcreador();
            Collection<Invitar> invitarCollectionOld = persistentEvento.getInvitarCollection();
            Collection<Invitar> invitarCollectionNew = evento.getInvitarCollection();
            List<String> illegalOrphanMessages = null;
            if (lugarOld != null && !lugarOld.equals(lugarNew)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain Lugar " + lugarOld + " since its idevento field is not nullable.");
            }
            for (Invitar invitarCollectionOldInvitar : invitarCollectionOld) {
                if (!invitarCollectionNew.contains(invitarCollectionOldInvitar)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Invitar " + invitarCollectionOldInvitar + " since its idevento field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (lugarNew != null) {
                lugarNew = em.getReference(lugarNew.getClass(), lugarNew.getId());
                evento.setLugar(lugarNew);
            }
            if (idcreadorNew != null) {
                idcreadorNew = em.getReference(idcreadorNew.getClass(), idcreadorNew.getId());
                evento.setIdcreador(idcreadorNew);
            }
            Collection<Invitar> attachedInvitarCollectionNew = new ArrayList<Invitar>();
            for (Invitar invitarCollectionNewInvitarToAttach : invitarCollectionNew) {
                invitarCollectionNewInvitarToAttach = em.getReference(invitarCollectionNewInvitarToAttach.getClass(), invitarCollectionNewInvitarToAttach.getId());
                attachedInvitarCollectionNew.add(invitarCollectionNewInvitarToAttach);
            }
            invitarCollectionNew = attachedInvitarCollectionNew;
            evento.setInvitarCollection(invitarCollectionNew);
            evento = em.merge(evento);
            if (lugarNew != null && !lugarNew.equals(lugarOld)) {
                Evento oldIdeventoOfLugar = lugarNew.getIdevento();
                if (oldIdeventoOfLugar != null) {
                    oldIdeventoOfLugar.setLugar(null);
                    oldIdeventoOfLugar = em.merge(oldIdeventoOfLugar);
                }
                lugarNew.setIdevento(evento);
                lugarNew = em.merge(lugarNew);
            }
            if (idcreadorOld != null && !idcreadorOld.equals(idcreadorNew)) {
                idcreadorOld.getEventoCollection().remove(evento);
                idcreadorOld = em.merge(idcreadorOld);
            }
            if (idcreadorNew != null && !idcreadorNew.equals(idcreadorOld)) {
                idcreadorNew.getEventoCollection().add(evento);
                idcreadorNew = em.merge(idcreadorNew);
            }
            for (Invitar invitarCollectionNewInvitar : invitarCollectionNew) {
                if (!invitarCollectionOld.contains(invitarCollectionNewInvitar)) {
                    Evento oldIdeventoOfInvitarCollectionNewInvitar = invitarCollectionNewInvitar.getIdevento();
                    invitarCollectionNewInvitar.setIdevento(evento);
                    invitarCollectionNewInvitar = em.merge(invitarCollectionNewInvitar);
                    if (oldIdeventoOfInvitarCollectionNewInvitar != null && !oldIdeventoOfInvitarCollectionNewInvitar.equals(evento)) {
                        oldIdeventoOfInvitarCollectionNewInvitar.getInvitarCollection().remove(invitarCollectionNewInvitar);
                        oldIdeventoOfInvitarCollectionNewInvitar = em.merge(oldIdeventoOfInvitarCollectionNewInvitar);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = evento.getId();
                if (findEvento(id) == null) {
                    throw new NonexistentEntityException("The evento with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Evento evento;
            try {
                evento = em.getReference(Evento.class, id);
                evento.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The evento with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Lugar lugarOrphanCheck = evento.getLugar();
            if (lugarOrphanCheck != null) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Evento (" + evento + ") cannot be destroyed since the Lugar " + lugarOrphanCheck + " in its lugar field has a non-nullable idevento field.");
            }
            Collection<Invitar> invitarCollectionOrphanCheck = evento.getInvitarCollection();
            for (Invitar invitarCollectionOrphanCheckInvitar : invitarCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Evento (" + evento + ") cannot be destroyed since the Invitar " + invitarCollectionOrphanCheckInvitar + " in its invitarCollection field has a non-nullable idevento field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Contacto idcreador = evento.getIdcreador();
            if (idcreador != null) {
                idcreador.getEventoCollection().remove(evento);
                idcreador = em.merge(idcreador);
            }
            em.remove(evento);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Evento> findEventoEntities() {
        return findEventoEntities(true, -1, -1);
    }

    public List<Evento> findEventoEntities(int maxResults, int firstResult) {
        return findEventoEntities(false, maxResults, firstResult);
    }

    private List<Evento> findEventoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Evento.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Evento findEvento(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Evento.class, id);
        } finally {
            em.close();
        }
    }

    public int getEventoCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Evento> rt = cq.from(Evento.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
    public Evento findMaxEvento()
    {
        EntityManager em = getEntityManager();
        try
        {
            Query q = em.createNamedQuery("Evento.findMaxEventoNo", Evento.class);
            return (Evento) q.getSingleResult();
        } finally
        {
            em.close();
        }
    }
    
}
